Next.jsã®ã€ã³ã¿ãŒã»ããã«ãŒããæ·±ãæãäžãããŠãŒã¶ãŒäœéšãåäžãããããã®å®çšçãªã¢ãŒãã«ãšãªãŒããŒã¬ã€ã®å®è£ æŠç¥ã玹ä»ããŸãã
Next.jsã®ã€ã³ã¿ãŒã»ããã«ãŒãïŒã¢ãŒãã«ãšãªãŒããŒã¬ã€ãã¿ãŒã³ããã¹ã¿ãŒãã
人æ°ã®Reactãã¬ãŒã ã¯ãŒã¯ã§ããNext.jsã¯ãããã©ãŒãã³ã¹ãé«ãã¹ã±ãŒã©ãã«ãªãŠã§ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®åŒ·åãªæ©èœãæäŸããŸãããã®äžã€ã§ããã€ã³ã¿ãŒã»ããã«ãŒãã¯ãç¹ã«ã¢ãŒãã«ããªãŒããŒã¬ã€ãã¿ãŒã³ãå®è£ ããéã«ãè€éãªã«ãŒãã£ã³ã°ã·ããªãªãæŽç·Žãããæ¹æ³ã§åŠçããææ®µãæäŸããŸãããã®å æ¬çãªã¬ã€ãã§ã¯ãã€ã³ã¿ãŒã»ããã«ãŒããæŽ»çšããŠãã·ãŒã ã¬ã¹ã§é åçãªãŠãŒã¶ãŒäœéšãçã¿åºãæ¹æ³ãæ¢ããŸãã
ã€ã³ã¿ãŒã»ããã«ãŒããšã¯ïŒ
ã€ã³ã¿ãŒã»ããã«ãŒãã䜿çšãããšãã«ãŒããã€ã³ã¿ãŒã»ããïŒææïŒãããã©ãŠã¶ã®URLã倿Žããããšãªãç°ãªãUIãã¬ã³ããªã³ã°ã§ããŸããããã¯ããŠãŒã¶ãŒäœéšãè±ãã«ããããã®äžæçãªè¿åè·¯ãšèããããšãã§ããŸããç¹ã«æ¬¡ã®ãããªå Žåã«åœ¹ç«ã¡ãŸãïŒ
- ã¢ãŒãã«ïŒæ°ããããŒãžã«ç§»åããã«ã¢ãŒãã«ãŠã£ã³ããŠã«ã³ã³ãã³ãã衚瀺ããã
- ãªãŒããŒã¬ã€ïŒæ¢åã®ã³ã³ãã³ãã®äžã«ä»å çãªæ å ±ãã³ã³ãããŒã«ã衚瀺ããã
- ç»åã®ã£ã©ãªãŒïŒç»åã®ã£ã©ãªãŒå ã§ã¹ã ãŒãºãªããŒãžã®ãããªããã²ãŒã·ã§ã³äœéšãäœæããã
- ãªã³ããŒãã£ã³ã°ãããŒïŒå®å šãªããŒãžãªããŒããªãã«ããŠãŒã¶ãŒãè€æ°ã¹ãããã®ããã»ã¹ã§ã¬ã€ãããã
ãªãã¢ãŒãã«ãšãªãŒããŒã¬ã€ã«ã€ã³ã¿ãŒã»ããã«ãŒãã䜿çšããã®ãïŒ
ã¢ãŒãã«ããªãŒããŒã¬ã€ãæ±ãåŸæ¥ã®ã¡ãœããã¯ãã³ã³ããŒãã³ãå ã§ç¶æ ã管çããããšãå€ãããããè€éåãããã©ãŒãã³ã¹ã®åé¡ã«ã€ãªããããšããããŸãããã€ã³ã¿ãŒã»ããã«ãŒãã«ã¯ããã€ãã®å©ç¹ããããŸãïŒ
- SEOã®åäžïŒã¢ãŒãã«ããªãŒããŒã¬ã€ã«è¡šç€ºãããã³ã³ãã³ãã¯ç¹å®ã®ã«ãŒãã«é¢é£ä»ããããŠãããããæ€çŽ¢ãšã³ãžã³ãããã¢ã¯ã»ã¹å¯èœã§ãã
- å ±æå¯èœãªURLïŒãŠãŒã¶ãŒã¯ã¢ãŒãã«ããªãŒããŒã¬ã€ã®ã³ã³ãã³ããžã®çŽæ¥ãªã³ã¯ãå ±æã§ããŸãã
- ãã©ãŠã¶å±¥æŽïŒãã©ãŠã¶ã®ãæ»ãããé²ãããã¿ã³ãæåŸ éãã«æ©èœãããŠãŒã¶ãŒã¯ã¢ãŒãã«å±¥æŽãããã²ãŒãã§ããŸãã
- ç¶æ 管çã®ç°¡çŽ åïŒã¢ãŒãã«ã®å¯èŠæ§ç¶æ ã®ç®¡çãç°¡çŽ åãããããã¯ãªãŒã³ã§ä¿å®æ§ã®é«ãã³ãŒãã«ãªããŸãã
- ããã©ãŒãã³ã¹ã®åäžïŒã¢ãŒãã«ã®ã³ã³ãã³ãã®ã¿ãæŽæ°ããããšã§ãäžèŠãªåã¬ã³ããªã³ã°ãåé¿ããŸãã
Next.jsã§ã®ã€ã³ã¿ãŒã»ããã«ãŒãã®èšå®
Eã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ã§åå詳现ã衚瀺ããã¢ãŒãã«ãäœæãããšããå®è·µçãªäŸãéããŠãã€ã³ã¿ãŒã»ããã«ãŒãã®å®è£ æ¹æ³ã説æããŸãã
ãããžã§ã¯ãæ§é
ãŸãããã£ã¬ã¯ããªæ§é ãå®çŸ©ããŸããããåååã«äžæã®IDãæã€`products`ãã£ã¬ã¯ããªããããšä»®å®ããŸãã
app/
products/
[id]/
page.js // åå詳现ããŒãž
@modal/
[id]/
page.js // åå詳现ã®ã¢ãŒãã«ã³ã³ãã³ã
default.js // productsãã£ã¬ã¯ããªã®ã¬ã€ã¢ãŠã
page.js // ããŒã ããŒãž
解説
- `app/products/[id]/page.js`: ããã¯ã¡ã€ã³ã®åå詳现ããŒãžã§ãã
- `app/products/@modal/[id]/page.js`: ããã¯ã¢ãŒãã«ã³ã³ãã³ããã¬ã³ããªã³ã°ããã€ã³ã¿ãŒã»ããã«ãŒããå®çŸ©ããŸãã`@modal`ãšããèŠçŽã«æ³šç®ããŠãã ãããããã¯Next.jsãã€ã³ã¿ãŒã»ããã«ãŒããèªèããããã«éèŠã§ãã
- `app/products/default.js`: ããã¯`products`ãã£ã¬ã¯ããªã®ã¬ã€ã¢ãŠãã§ãã`@modal`ã«ãŒãããã®ã¬ã€ã¢ãŠãå ã«ã©ããããå¿ èŠããããŸãã
- `app/page.js`: ããŒã ããŒãžã§ãååãžã®ãªã³ã¯ãå«ãŸããŸãã
ã³ãŒãå®è£
1. ããŒã ããŒãž (app/page.js)
ãã®ããŒãžã¯ååã®ãªã¹ãã衚瀺ããåååã«ã¯åå詳现ãã¢ãŒãã«ã§éããªã³ã¯ããããŸãã
// app/page.js
import Link from 'next/link';
const products = [
{ id: '1', name: 'Laptop' },
{ id: '2', name: 'Smartphone' },
{ id: '3', name: 'Tablet' },
];
export default function Home() {
return (
Product List
{products.map((product) => (
-
{product.name}
))}
);
}
2. åå詳现ããŒãž (app/products/[id]/page.js)
ãã®ããŒãžã¯å®å šãªåå詳现ãã¬ã³ããªã³ã°ããŸããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãAPIãããŒã¿ããŒã¹ããããŒã¿ãååŸããŸããéèŠãªã®ã¯ãå ã®ååäžèŠ§ã«æ»ãããã®ãªã³ã¯ãæäŸããããšã§ãã
// app/products/[id]/page.js
import Link from 'next/link';
export default function ProductDetails({ params }) {
const { id } = params;
return (
Product Details
Product ID: {id}
This is the full product details page.
Back to Product List
);
}
3. ã¢ãŒãã«ã³ã³ãã³ã (app/products/@modal/[id]/page.js)
ãããéèŠãªéšåãã€ã³ã¿ãŒã»ããã«ãŒãã§ããåãååIDã䜿çšããŠã¢ãŒãã«ã³ã³ãã³ããã¬ã³ããªã³ã°ããŸããIDã«ã¢ã¯ã»ã¹ããããã«`useParams`ããã¯ã䜿çšããŠããç¹ã«æ³šç®ããŠãã ããã
// app/products/@modal/[id]/page.js
'use client';
import { useParams } from 'next/navigation';
import styles from './modal.module.css';
export default function ProductModal() {
const params = useParams();
const { id } = params;
return (
);
}
泚ïŒ`'use client';`ãã£ã¬ã¯ãã£ãã¯ãç¹ã«`useParams`ã䜿çšããå Žåãªã©ãã¯ã©ã€ã¢ã³ããµã€ãã®ã€ã³ã¿ã©ã¯ãã£ãæ§ã®ããã«å¿ èŠã§ãã
ã¹ã¿ã€ãªã³ã° (modal.module.css): åºæ¬çãªã¢ãŒãã«ã®ã¹ã¿ã€ãªã³ã°ã«ã¯ãã·ã³ãã«ãªCSSã¢ãžã¥ãŒã«ã䜿çšãããŸããããã¯ã¢ãŒãã«ãæ£ããé 眮ããããã«éèŠã§ãã
/* modal.module.css */
.modalOverlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000; /* Ensure it's on top */
}
.modalContent {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
width: 80%;
max-width: 600px;
}
4. ã¬ã€ã¢ãŠã (app/products/default.js)
ãã®ã¬ã€ã¢ãŠãã¯`@modal`ã«ãŒããã©ãããããããååã³ã³ããã¹ãå ã§ã¬ã³ããªã³ã°ãããããšãä¿èšŒããŸãã
// app/products/default.js
export default function ProductsLayout({ children }) {
return (
{children}
);
}
ä»çµã¿
- ããŒã ããŒãžã§ãŠãŒã¶ãŒãååãªã³ã¯ïŒäŸïŒ`/products/1`ïŒãã¯ãªãã¯ãããšãNext.jsã¯ããã`products`ãã£ã¬ã¯ããªå ã®ã«ãŒããšããŠèªèããŸãã
- `@modal`ã€ã³ã¿ãŒã»ããã«ãŒãããããããNext.jsã¯`@modal`以äžã«äžèŽããã«ãŒãããããã©ããããã§ãã¯ããŸãã
- äžèŽãèŠã€ãã£ãå ŽåïŒäŸïŒ`/products/@modal/1`ïŒãNext.jsã¯`app/products/@modal/[id]/page.js`ã®ã³ã³ãã³ããçŸåšã®ããŒãžå ã«ã¬ã³ããªã³ã°ããŸãããã©ãŠã¶ã®URLã¯`/products/1`ã®ãŸãŸã§ãã
- `modalOverlay`ã®ã¹ã¿ã€ã«ããã¢ãŒãã«ãåºç€ãšãªãã³ã³ãã³ãã®äžã«é 眮ããŸãã
- ãClose Modalããã¯ãªãã¯ãããš`history.back()`ã䜿çšãããåã®ç¶æ ã«æ»ãããšã§å¹æçã«ã¢ãŒãã«ãéããŸãã
ã€ã³ã¿ãŒã»ããã«ãŒãã®é«åºŠãªãã¯ããã¯
1. æ»ããã¿ã³ã®åŠç
ã¢ãŒãã«å®è£ ã®éèŠãªåŽé¢ã¯ããã©ãŠã¶ã®æ»ããã¿ã³ã®é©åãªåäœãä¿èšŒããããšã§ãããŠãŒã¶ãŒãã¢ãŒãã«ãéããŠããæ»ããã¿ã³ãã¯ãªãã¯ããå Žåãçæ³çã«ã¯ã¢ããªã±ãŒã·ã§ã³ããé¢ããã®ã§ã¯ãªããã¢ãŒãã«ãéããŠä»¥åã®ã³ã³ããã¹ãã«æ»ãã¹ãã§ãã
äŸã§äœ¿çšãããŠãã`history.back()`ã¡ãœããã¯ããã©ãŠã¶å±¥æŽã1ã¹ãããæ»ãããšã§ãã®å¹æãå®çŸããŸããããããããè€éãªã·ããªãªã§ã¯ãçŸåšã®ã«ãŒãã£ã³ã°ç¶æ ãèæ ®ããã«ã¹ã¿ã ã®æ»ããã¿ã³ãã³ãã©ãå®è£ ããå¿ èŠããããããããŸããã
2. åçãªã¢ãŒãã«ã³ã³ãã³ã
å®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã¢ãŒãã«ã®ã³ã³ãã³ãã¯ååIDã«åºã¥ããŠAPIãããŒã¿ããŒã¹ããåçã«ååŸãããããšãã»ãšãã©ã§ããã¢ãŒãã«ã³ã³ããŒãã³ãå ã§`fetch` APIãSWRãReact Queryã®ãããªããŒã¿ãã§ããã³ã°ã©ã€ãã©ãªã䜿çšããŠãå¿ èŠãªããŒã¿ãååŸã§ããŸãã
// app/products/@modal/[id]/page.js
'use client';
import { useParams } from 'next/navigation';
import { useState, useEffect } from 'react';
export default function ProductModal() {
const params = useParams();
const { id } = params;
const [product, setProduct] = useState(null);
useEffect(() => {
async function fetchProduct() {
const res = await fetch(`/api/products/${id}`); // ããªãã®APIãšã³ããã€ã³ãã«çœ®ãæããŠãã ãã
const data = await res.json();
setProduct(data);
}
fetchProduct();
}, [id]);
if (!product) {
return Loading...
;
}
return (
{product.name}
{product.description}
{/* ... ãã®ä»ã®åå詳现 ... */}
history.back()}>Close Modal
);
}
3. ãã¹ããããã¢ãŒãã«
ã€ã³ã¿ãŒã»ããã«ãŒãã¯ãã¹ãããŠãè€éãªã¢ãŒãã«ã¯ãŒã¯ãããŒãäœæã§ããŸããäŸãã°ããŠãŒã¶ãŒãåå詳现ã¢ãŒãã«ãéãããããããã¿ã³ãã¯ãªãã¯ããŠé¢é£ååã®ã¢ãŒãã«ãéããšãã£ãå Žåã§ããããã¯`@modal`ãã£ã¬ã¯ããªå ã«è¿œå ã®ã€ã³ã¿ãŒã»ããã«ãŒããäœæããããšã§å®çŸã§ããŸãã
4. 404ãšã©ãŒã®åŠç
ãŠãŒã¶ãŒãç¡å¹ãªååIDãæã€ã¢ãŒãã«URLïŒäŸïŒ`/products/@modal/nonexistent`ïŒã«ããã²ãŒãããã·ããªãªãèããŠã¿ãŸãããããŠãŒã¶ãŒãã¬ã³ããªãŒãª404ããŒãžã衚瀺ãããããŠãŒã¶ãŒãæå¹ãªååããŒãžã«ãªãã€ã¬ã¯ãããããã«ãé©åãªãšã©ãŒãã³ããªã³ã°ãå®è£ ãã¹ãã§ãã
// app/products/@modal/[id]/page.js
// ... (ã³ã³ããŒãã³ãã®æ®ãã®éšå)
if (!product) {
return Product not found.
; // ãŸãã¯404ããŒãžã«ãªãã€ã¬ã¯ã
}
// ... (ã³ã³ããŒãã³ãã®æ®ãã®éšå)
5. ãªãŒããŒã¬ã€ãã¿ãŒã³
ãããŸã§ã®äŸã¯ã¢ãŒãã«ã«çŠç¹ãåœãŠãŠããŸããããã€ã³ã¿ãŒã»ããã«ãŒãã¯ãªãŒããŒã¬ã€ã«ã䜿çšã§ããŸããã³ã³ãã³ããäžå€®ã«é 眮ãã代ããã«ããªãŒããŒã¬ã€ã¯ãµã€ãããŒãšããŠè¡šç€ºãããããç»é¢ã®æšªããã¹ã©ã€ãã€ã³ããããã«ãšããŠè¡šç€ºããããããããšããããŸããCSSã®ã¹ã¿ã€ãªã³ã°ã¯ç°ãªããŸãããã«ãŒãã£ã³ã°ã®ããžãã¯ã¯åãã§ãã
å®äžçã®äŸãšãŠãŒã¹ã±ãŒã¹
- Eã³ããŒã¹ïŒåå詳现ãã·ã§ããã³ã°ã«ãŒãã®æŠèŠããŸãã¯ãã§ãã¯ã¢ãŠããããŒãã¢ãŒãã«ããªãŒããŒã¬ã€ã§è¡šç€ºããã
- ãœãŒã·ã£ã«ã¡ãã£ã¢ïŒç»åãã¬ãã¥ãŒãã³ã¡ã³ãã»ã¯ã·ã§ã³ããŸãã¯ãŠãŒã¶ãŒãããã£ãŒã«ãã¢ãŒãã«ã§è¡šç€ºããã
- ããã¥ã¡ã³ã管çïŒããã¥ã¡ã³ããã¬ãã¥ãŒãç·šéããŒã«ããŸãã¯ããŒãžã§ã³å±¥æŽããªãŒããŒã¬ã€ã§è¡šç€ºããã
- å°å³ã¢ããªã±ãŒã·ã§ã³ïŒå Žæã®è©³çްãèå³ã®ãããã€ã³ãããŸãã¯ã«ãŒãæ å ±ããªãŒããŒã¬ã€ã§è¡šç€ºããã
- CRMã·ã¹ãã ïŒé£çµ¡å ã®è©³çްãã¢ã¯ãã£ããã£ãã°ããŸãã¯è²©å£²æ©äŒãã¢ãŒãã«ã§è¡šç€ºããã
äŸïŒåœéEã³ããŒã¹ãã©ãããã©ãŒã ã°ããŒãã«ãªEã³ããŒã¹ãµã€ããæ³åããŠã¿ãŠãã ããããŠãŒã¶ãŒãååãã¯ãªãã¯ãããšã詳现ãã¢ãŒãã«ã§éããŸããURLã¯`/products/[product_id]`ã«å€ãããçŽæ¥ãªã³ã¯ãSEOã®å©ç¹ãåŸãããŸãããããŠãŒã¶ãŒãã¢ãŒãã«ããŒãžã§èšèªãåãæ¿ããå ŽåïŒäŸïŒè±èªããã¹ãã€ã³èªãžïŒãåå詳现ãéžæãããèšèªã§ååŸãããã¢ãŒãã«ã®ã³ã³ãã³ãã¯ã·ãŒã ã¬ã¹ã«æŽæ°ãããŸããããã«ããµã€ãã¯ïŒåæãåŸãŠïŒãŠãŒã¶ãŒã®æåšå°ãæ€åºãããã®å°åã«é¢é£ããé éæ å ±ãã¢ãŒãã«å ã«è¡šç€ºããããšãã§ããŸãã
ã€ã³ã¿ãŒã»ããã«ãŒãã䜿çšããéã®ãã¹ããã©ã¯ãã£ã¹
- ã¢ãŒãã«ã®ã³ã³ãã³ãã¯ç°¡æœã«ïŒã¢ãŒãã«ã«æ å ±ãå€ãããªãããã«ããŸããæ¬è³ªçãªè©³çްãæç€ºããããšã«éäžããŠãã ããã
- æç¢ºãªããã²ãŒã·ã§ã³ãæäŸããïŒãŠãŒã¶ãŒãç°¡åã«ã¢ãŒãã«ãéããŠä»¥åã®ã³ã³ããã¹ãã«æ»ããããã«ããŸãã
- ã¢ãã€ã«åãã«æé©åããïŒã¢ãŒãã«ã®ã¬ã€ã¢ãŠããã¬ã¹ãã³ã·ãã«ããå°ããªç»é¢ã§ã䜿ããããããã«èšèšããŸãã
- 培åºçã«ãã¹ãããïŒç°ãªããã©ãŠã¶ãããã€ã¹ã§ã¢ãŒãã«ã®åäœããã¹ãããäžè²«ããäœéšãä¿èšŒããŸãã
- ã¢ã¯ã»ã·ããªãã£ãèæ ®ããïŒé©åãªARIA屿§ãšããŒããŒãããã²ãŒã·ã§ã³ãå®è£ ããé害ãæã€ãŠãŒã¶ãŒãã¢ãŒãã«ã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãã
ã€ã³ã¿ãŒã»ããã«ãŒãã®ä»£æ¿æ¡
ã€ã³ã¿ãŒã»ããã«ãŒãã¯ã¢ãŒãã«ããªãŒããŒã¬ã€ãã¿ãŒã³ã«å¯ŸããŠåŒ·åãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸãããä»ã®ã¢ãããŒããæ€èšã§ããŸãïŒ
- åŸæ¥ã®ç¶æ 管çïŒReactã®`useState`ããã¯ãReduxãZustandã®ãããªç¶æ 管çã©ã€ãã©ãªã䜿çšããŠã¢ãŒãã«ã®å¯èŠæ§ãå¶åŸ¡ãããããã¯éåžžã«åºæ¬çãªã¢ãŒãã«å®è£ ã«ã¯ç°¡åã§ãããã¹ã±ãŒã«ã倧ãããªããšç®¡çãé£ãããªããŸãã
- ãµãŒãããŒãã£ã®ã¢ãŒãã«ã©ã€ãã©ãªïŒReact ModalãMaterial UIã®ãããªã©ã€ãã©ãªããæäŸãããæ¢è£œã®ã¢ãŒãã«ã³ã³ããŒãã³ããå©çšããããããã¯è¿ éãªãœãªã¥ãŒã·ã§ã³ãæäŸã§ããŸãããã«ã¹ã¿ãã€ãºã®éžæè¢ãå¶éãããå¯èœæ§ããããŸãã
- ã¯ã©ã€ã¢ã³ããµã€ãã«ãŒãã£ã³ã°ã©ã€ãã©ãªïŒReact Routerã®ãããªã©ã€ãã©ãªã䜿çšããŠãã¯ã©ã€ã¢ã³ããµã€ãã®ã«ãŒãã£ã³ã°ãšã¢ãŒãã«ã®å¯èŠæ§ã管çããã
çµè«
Next.jsã®ã€ã³ã¿ãŒã»ããã«ãŒãã¯ããŠã§ãã¢ããªã±ãŒã·ã§ã³ã«ã¢ãŒãã«ããªãŒããŒã¬ã€ãã¿ãŒã³ãå®è£ ããããã®å ç¢ã§æŽç·Žãããæ¹æ³ãæäŸããŸãããã®åŒ·åãªæ©èœã掻çšããããšã§ãã·ãŒã ã¬ã¹ã§SEOãã¬ã³ããªãŒããã€ãŠãŒã¶ãŒãã¬ã³ããªãŒãªäœéšãäœãåºãããšãã§ããŸãã代æ¿ã¢ãããŒããååšããŸãããã€ã³ã¿ãŒã»ããã«ãŒãã¯ç¬èªã®å©ç¹ã®çµã¿åãããæäŸããNext.jséçºè ã®æŠåšåº«ã«ãããŠäŸ¡å€ããããŒã«ãšãªããŸãã